﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TSOL.FastSPWeb.ValueObjects;
using Microsoft.SharePoint;
using System.Threading;

namespace TSOL.FastSPWeb.Core
{
    internal class FastSPQueryFactoryThread
    {
        static Thread FastSPQueryFactoryThreadObject;

        public static void Start()
        {
            (FastSPQueryFactoryThreadObject = new Thread(FastSPQueryFactoryThreadTaskAsync)).Start();
        }
        public static void Stop()
        {
            FastSPQueryFactoryThreadObject.Abort();
        }

        static void FastSPQueryFactoryThreadTaskAsync()
        {
            while ((Thread.CurrentThread.ThreadState != ThreadState.AbortRequested) && (Thread.CurrentThread.ThreadState != ThreadState.StopRequested) && (Thread.CurrentThread.ThreadState != ThreadState.SuspendRequested))
            {
                Thread.Sleep(2 * 60 * 1000); // 2 min. 
                if (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.QueryCacheDictionary.Count > 0)
                {
                    lock (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.QueryCacheDictionary)
                    {
                        foreach (SPQueryCacheCollection _SPCacheCollection in FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.QueryCacheDictionary.Values)
                        {
                            // We only cache Elevated items in multiple copies.
                            if (_SPCacheCollection.MaxCopiesOfElevatedItems > -1)
                            {
                                if (_SPCacheCollection.WaitingForFreeItems == 0)
                                    _SPCacheCollection.MaxCopiesOfElevatedItems--;
                                else
                                    if (_SPCacheCollection.WaitingForFreeItems > 1000)
                                        _SPCacheCollection.MaxCopiesOfElevatedItems = _SPCacheCollection.MaxCopiesOfElevatedItems + 5;
                                    else
                                        if (_SPCacheCollection.WaitingForFreeItems > 1)
                                            _SPCacheCollection.MaxCopiesOfElevatedItems = _SPCacheCollection.MaxCopiesOfElevatedItems++;

                                if (_SPCacheCollection.WaitingForFreeItems < 0)
                                    _SPCacheCollection.WaitingForFreeItems = 0;

                                _SPCacheCollection.WaitingForFreeItems = 0;
                                if (_SPCacheCollection.Count() < _SPCacheCollection.MaxCopiesOfElevatedItems)
                                {
                                    lock (_SPCacheCollection)
                                    {
                                        int deltaCopies = _SPCacheCollection.MaxCopiesOfElevatedItems - _SPCacheCollection.Count();
                                        for (int ix = 0; ix < deltaCopies; ix++)
                                        {
                                            SPQueryCacheEntity Entity = new SPQueryCacheEntity();
                                            FastSPWebCall.OpenElevatedWeb(_SPCacheCollection.SiteGuid, _SPCacheCollection.WebGuid,
                                                (_site, _web, hashCode) =>
                                                {
                                                    SPList _list = null;
                                                    _web.FastLists(FastSPWebCallExtensions.CachePolicy.FastSPDefault, (Lists) =>
                                                    {
                                                        _list = Lists[_SPCacheCollection.ListGuid];
                                                        Entity.Items = _list.GetItems(_SPCacheCollection.Query);
                                                        Entity.Created = DateTime.Now;
                                                        Entity.Free = true;
                                                        _SPCacheCollection.Add(Entity);
                                                    });
                                                });
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        public static void FastSPQueryFactoryThreadTask(SPList List, SPUserToken CurrentUserToken, int HashKey, SPQueryCacheCollection SPQueryCacheCollectionObject)
        {
            lock (SPQueryCacheCollectionObject)
            {
                for (int ix = 0; ix < 1; ix++)
                {
                    SPQueryCacheEntity Entity;
                    lock(Entity = new SPQueryCacheEntity()) {
                        Entity.UserToken = CurrentUserToken;
                        Entity.Free = true;
                        Entity.Items = List.GetItems(SPQueryCacheCollectionObject.Query);
                        int _tmp = Entity.Items.Count;
                        Entity.Created = DateTime.Now;
                        SPQueryCacheCollectionObject.Add(Entity);
                        SPQueryCacheCollection tempSPQueryCacheCollection = null;
                        lock (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.QueryCacheDictionary)
                        {
                            if (!FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.QueryCacheDictionary.TryGetValue(HashKey, out tempSPQueryCacheCollection))
                                FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.QueryCacheDictionary.Add(HashKey, SPQueryCacheCollectionObject);
                        }
                    }
                }
            }

        }
    }
}